package edu.thu.thss.yxy.sip;

import edu.thu.thss.yxy.audionotifier.AlertManager;
import edu.thu.thss.yxy.gui.GuiCallback;
import edu.thu.thss.yxy.sip.event.CallStateEvent;
import edu.thu.thss.yxy.sip.event.CallStateListener;

/**
 * The CallPeer is an class that represents peers in a call.
 * 
 * @author Andy Gao
 * 
 */
public class CallPeer implements CallStateListener {
	private Call call;
	private GuiCallback guiCallback;
	private String peerId;

	public CallPeer(Call call) {
		this.call = call;
		call.addCallStateListener(this);
//		this.peerId = String.valueOf(System.currentTimeMillis())
//		+ String.valueOf(hashCode());
		this.peerId = call.getCallID();
	}

	/**
	 * Returns a unique identifier representing this peer. Identifiers returned
	 * by this method should remain unique across calls. In other words, if it
	 * returned the value of "A" for a given peer it should not return that same
	 * value for any other peer and return a different value even if the same
	 * person (address) is participating in another call. Values need not remain
	 * unique after restarting the program.
	 * 
	 * @return an identifier representing this call peer.
	 */
	public String getPeerID() {
		return this.peerId;
	}

	/**
	 * Returns a reference to the call that this peer belongs to.
	 * 
	 * @return a reference to the call containing this peer.
	 */
	public Call getCall() {
		return call;
	}

	/**
	 * Returns a human readable name representing this peer.
	 * 
	 * @return a String containing a name for that peer.
	 */
	public String getDisplayName() {
		return call.getRemoteName();
	}

	/**
	 * Returns a String locator for that peer. A locator might be a SIP URI, an
	 * IP address or a telephone number.
	 * 
	 * @return the peer's address or phone number.
	 */
	public String getAddress() {
		return call.getAddress();
	}

	/**
	 * Returns an object representing the current state of that peer.
	 * CallPeerState may vary among CONNECTING, RINGING, CALLING, BUSY,
	 * CONNECTED, and others, and it reflects the state of the connection
	 * between us and that peer.
	 * 
	 * @return a CallPeerState instance representing the peer's state.
	 */
	public CallState getState() {
		return call.getCallState();
	}

	/**
	 * Allows the user interface to register a listener interested in changes
	 * 
	 * @param listener
	 *            a listener instance to register with this peer.
	 */
	public void setCallback(GuiCallback callback) {
		this.guiCallback = callback;
	}

	public void callStateChanged(CallStateEvent evt) {
		guiCallback.updateCallPeer(this);

		if (evt.getNewState() == CallState.DISCONNECTED
				||evt.getNewState() == CallState.FAILED)
			guiCallback.removeCallPeer(this);

		// ----- Alerts
		if (evt.getNewState() != evt.getOldState()) {
			if (evt.getOldState() == CallState.ALERTING)
				guiCallback.stopAlert(AlertManager.ALERTING);
			else if (evt.getOldState() == CallState.RINGING)
				guiCallback.stopAlert(AlertManager.RINGING);
			else if (evt.getOldState() == CallState.BUSY)
				guiCallback.stopAlert(AlertManager.BUSY);

			// Start current alert
			if (evt.getNewState() == CallState.ALERTING)
				guiCallback.startAlert(AlertManager.ALERTING);
			else if (evt.getNewState() == CallState.RINGING)
				guiCallback.startAlert(AlertManager.RINGING);
			else if (evt.getNewState() == CallState.BUSY)
				guiCallback.startAlert(AlertManager.BUSY);
		}
	}
}
